<template>
  <div class="modalWrap" :class="{undestroy: isDestroy === false}" :style="{zIndex: zIndex_}" v-show="isShowWrap" @click="isCloseOnClickBg && close()" ref="wrap">
    <transition :name="needAnim ? 'modal' : ''" v-on:after-leave="afterLeave">
    <div :class="'modal' + (modalClass ? (' ' + modalClass) : '')" :style="{zIndex: zIndex_, backgroundColor: bgColor}" v-show="isShowModal" @click.stop ref="modal">
      <h3 class="head" v-if="title" v-html="title_"> </h3>
      <img v-if="isShowCloseBtn" class="close" src="./images/close.png" @click="close">
      <div class="body">
        <slot></slot>
      </div>
      <div class="foot" v-if="noText || okText">
        <button type="button" class="btn ok" @click="handleOk" v-if="okText" v-text="okText_"></button>
        <button type="button" class="btn no" @click="handleNo" v-if="noText" v-text="noText_"></button>
      </div>
    </div>
    </transition>
  </div>
</template>

<script>
import store from '@/store/index.js'

export default {
  name: 'swmodal',
  props: {
    isDestroy: true,
    isShow: false,
    needAnim: {
      default: true
    },
    modalClass: '',
    isShowBg: { // 定义了default都有初始值
      default: true
    },
    isCloseOnClickBg: {
      default: false
    },
    noText: {
      type: [String, Function],
      default: ''
    },
    okText: {
      type: [String, Function],
      default: ''
    },
    title: {
      type: [String, Function],
      default: ''
    },
    bgColor: {
      default: '#1A1F2B'
    },
    no: {
      type: Function
    },
    ok: {
      type: Function
    },
    onClosed: {
      type: Function
    },
    zIndex: 0,
    isNormalText: {
      default: false
    },
    isShowCloseBtn: {
      default: false
    }
  },
  computed: {
    lang () {
      return store.state.lang.lang
    },
    title_ () {
      return this.getText('title')
    },
    okText_ () {
      return this.getText('okText')
    },
    noText_ () {
      return this.getText('noText')
    }
  },
  watch: {
    isShow (nv, ov) {
      if (nv === this.isShowModal) return // 若状态一样则不必再执行，有时会发现toggle(false)会执行两次
      this.toggle(nv)
    },
    isShowModal (nv) {
      this.$emit('update:isShow', nv)
    },
    zIndex (nv) {
      global.swModalZIndex = nv
    }
  },
  data () {
    return {
      isShowWrap: false, // 由于不能更改props里的值，故用另一个变量代替
      isShowModal: false,
      zIndex_: 1
    }
  },
  methods: {
    getText (name) {
      if (this.isNormalText) return this[name] // 普通文本
      if (!this[name]) return '' // 空
      if (this._.isFunction(this[name])) {
        return this[name]()
      }
      if (this._.isString(this[name]) && this.lang[this[name]]) {
        return this.lang[this[name]]
      }
      return this[name]
    },
    afterLeave () {
      this.isShowWrap = false
      typeof this.onClosed === 'function' && this.onClosed()
    },
    init () {
      // 若无背景则将背景移除
      if (!this.isShowBg) {
        this.$nextTick(() => { // 通过ModalApi调用一定要写nextTick，因为通过$mount手动挂载仍需要等一会节点才出来
          let wrap = this.$refs.wrap
          let wrapParent = wrap.parentNode
          let modal = this.$refs.modal
          wrapParent.removeChild(wrap)
          document.querySelector('body').appendChild(modal)
        })
      } else {
        let wrap = this.$refs.wrap
        document.querySelector('body').appendChild(wrap)
      }
    },
    toggle (toggle) {
      if (toggle === true) {
        this.increaseZIndex()

        this.isShowWrap = true
        this.isShowModal = true
      }

      if (toggle === false) {
        this.isShowModal = false
      }
    },
    close () {
      this.toggle(false)
    },
    handleNo () {
      if (this.no) {
        this.no()
        return
      }

      this.close()
    },
    handleOk () {
      if (this.ok) {
        this.ok()
        // return
      }

      // this.close()
    },
    handleClickBg () {
      if (this.clickBg) {
        this.clickBg()
      }
    },
    increaseZIndex () {
      if (global.swModalZIndex === undefined) {
        global.swModalZIndex = 1
      } else {
        global.swModalZIndex ++
      }
      this.zIndex_ = global.swModalZIndex
    }
  },
  mounted () {
    global.swModalZIndex = this.zIndex || global.swModalZIndex

    this.init()
    this.isShow && this.toggle(this.isShow) // 默认是false，不必调用toggle函数
  },
  // 由于组件是添加到body节点的，所以离开页面后，vue组件实例是销毁了，但是节点还在，需要手动删除
  beforeDestroy () {
    if (this.isShowBg) {
      let wrap = this.$refs.wrap
      let parent = wrap.parentNode
      if (!wrap || !parent) return // 此句是应对modal api里的destroyAll
      parent.removeChild(wrap)
    } else {
      let modal = this.$refs.modal
      let parent = modal.parentNode
      if (!modal || !parent) return
      parent.removeChild(modal)
    }
  }
}
</script>

<style lang="less">
.modalWrap {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 99;
}
.modal {
  position: fixed;
  z-index: 999;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -52%) scale(1, 1);
  background: #1A1F2B;
  border-radius: 4px;

  .body {
    line-height: 24px;
  }
}

.modal .head {
  position: relative;
  font-size: 14px;
  height: 24px;
  line-height: 24px;
  padding:10px 0;
  margin:0 20px;
  background: #1A1F2B;
  color: #fff;
  border-bottom: solid 1px #444c56;
}
.modal .close {
  position: absolute;
  top: 17px;
  right: 20px;
  width: 12px;
  height: 12px;
  cursor: pointer;

}
.modal .foot {
  padding: 0 20px 20px;
  text-align: center;
}
.modal .btn {
  font-size: 12px;
  display: inline-block;
  height: 40px;
  line-height: 40px;
  border-radius: 2px;
  width: 220px;
  background-color: #3782FF;
  color: #fff;
}
.modal .btn.no {
  margin-left: 20px;
  margin-right: 20px;
  background-color: #2A3441;
}
.modal .btn.ok {
  margin-left: 20px;
  margin-right: 20px;
}

.modal-enter { // 进入
  opacity: 0;
  transform: translate(-50%, -52%) scale(.7, .7);
}
.modal-enter-active { // 进入后
  transition: all .2s ease;
}
.modal-enter-to { // 进入结束
  transform: translate(-50%, -52%) scale(1, 1);
  opacity: 1;
}

.modal-leave { // 离开
  transform: translate(-50%, -52%) scale(1, 1);
}
.modal-leave-active { // 离开的过渡
  transition: all .2s;
}
.modal-leave-to { // 离开结束
  transform: translate(-50%, -52%) scale(.7, .7);
  opacity: 0;
}

</style>
